home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 7: Programming / CDAT7.iso / Share / Codigo / hh / rsource.exe / Heretic Source / P_DOORS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-13  |  7.9 KB  |  369 lines

  1.  
  2. // P_doors.c
  3.  
  4. #include "DoomDef.h"
  5. #include "P_local.h"
  6. #include "soundst.h"
  7.  
  8. //==================================================================
  9. //==================================================================
  10. //
  11. //                            VERTICAL DOORS
  12. //
  13. //==================================================================
  14. //==================================================================
  15.  
  16. //==================================================================
  17. //
  18. //    T_VerticalDoor
  19. //
  20. //==================================================================
  21. void T_VerticalDoor(vldoor_t *door)
  22. {
  23.     result_e res;
  24.  
  25.     switch(door->direction)
  26.     {
  27.         case 0: // WAITING
  28.             if(!--door->topcountdown)
  29.                 switch(door->type)
  30.                 {
  31.                     case normal:
  32.                         door->direction = -1; // time to go back down
  33.                         S_StartSound((mobj_t *)
  34.                             &door->sector->soundorg, sfx_doropn);
  35.                         break;
  36.                     case close30ThenOpen:
  37.                         door->direction = 1;
  38.                         S_StartSound((mobj_t *)
  39.                             &door->sector->soundorg, sfx_doropn);
  40.                         break;
  41.                     default:
  42.                         break;
  43.                 }
  44.             break;
  45.         case 2: // INITIAL WAIT
  46.             if(!--door->topcountdown)
  47.             {
  48.                 switch(door->type)
  49.                 {
  50.                     case raiseIn5Mins:
  51.                         door->direction = 1;
  52.                         door->type = normal;
  53.                         S_StartSound((mobj_t *)
  54.                             &door->sector->soundorg, sfx_doropn);
  55.                         break;
  56.                     default:
  57.                         break;
  58.                 }
  59.             }
  60.             break;
  61.         case -1: // DOWN
  62.             res = T_MovePlane(door->sector, door->speed,
  63.                 door->sector->floorheight, false, 1, door->direction);
  64.             if(res == pastdest)
  65.             {
  66.                 switch(door->type)
  67.                 {
  68.                     case normal:
  69.                     case close:
  70.                         door->sector->specialdata = NULL;
  71.                         P_RemoveThinker(&door->thinker);  // unlink and free
  72.                         S_StartSound((mobj_t *)
  73.                             &door->sector->soundorg, sfx_dorcls);
  74.                         break;
  75.                     case close30ThenOpen:
  76.                         door->direction = 0;
  77.                         door->topcountdown = 35*30;
  78.                         break;
  79.                     default:
  80.                         break;
  81.                 }
  82.             }
  83.             else if(res == crushed)
  84.             {
  85.                 switch(door->type)
  86.                 {
  87.                     case close: // DON'T GO BACK UP!
  88.                         break;
  89.                     default:
  90.                         door->direction = 1;
  91.                         S_StartSound((mobj_t *)
  92.                             &door->sector->soundorg,sfx_doropn);
  93.                         break;
  94.                 }
  95.             }
  96.             break;
  97.         case 1: // UP
  98.             res = T_MovePlane(door->sector, door->speed,
  99.                 door->topheight, false, 1, door->direction);
  100.             if(res == pastdest)
  101.             {
  102.                 switch(door->type)
  103.                 {
  104.                     case normal:
  105.                         door->direction = 0; // wait at top
  106.                         door->topcountdown = door->topwait;
  107.                         break;
  108.                     case close30ThenOpen:
  109.                     case open:
  110.                         door->sector->specialdata = NULL;
  111.                         P_RemoveThinker (&door->thinker); // unlink and free
  112.                         S_StopSound((mobj_t *)&door->sector->soundorg);
  113.                         break;
  114.                     default:
  115.                         break;
  116.                 }
  117.             }
  118.             break;
  119.     }
  120. }
  121.  
  122. //----------------------------------------------------------------------------
  123. //
  124. // EV_DoDoor
  125. //
  126. // Move a door up/down
  127. //
  128. //----------------------------------------------------------------------------
  129.  
  130. int EV_DoDoor(line_t *line, vldoor_e type, fixed_t speed)
  131. {
  132.     int secnum;
  133.     int retcode;
  134.     sector_t *sec;
  135.     vldoor_t *door;
  136.  
  137.     secnum = -1;
  138.     retcode = 0;
  139.     while((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0)
  140.     {
  141.         sec = §ors[secnum];
  142.         if(sec->specialdata)
  143.         {
  144.             continue;
  145.         }
  146.         // Add new door thinker
  147.         retcode = 1;
  148.         door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0);
  149.         P_AddThinker(&door->thinker);
  150.         sec->specialdata = door;
  151.         door->thinker.function = T_VerticalDoor;
  152.         door->sector = sec;
  153.         switch(type)
  154.         {
  155.             case close:
  156.                 door->topheight = P_FindLowestCeilingSurrounding(sec);
  157.                 door->topheight -= 4*FRACUNIT;
  158.                 door->direction = -1;
  159.                 S_StartSound((mobj_t *)&door->sector->soundorg, sfx_doropn);
  160.                 break;
  161.             case close30ThenOpen:
  162.                 door->topheight = sec->ceilingheight;
  163.                 door->direction = -1;
  164.                 S_StartSound((mobj_t *)&door->sector->soundorg, sfx_doropn);
  165.                 break;
  166.             case normal:
  167.             case open:
  168.                 door->direction = 1;
  169.                 door->topheight = P_FindLowestCeilingSurrounding(sec);
  170.                 door->topheight -= 4*FRACUNIT;
  171.                 if(door->topheight != sec->ceilingheight)
  172.                 {
  173.                     S_StartSound((mobj_t *)&door->sector->soundorg,
  174.                         sfx_doropn);
  175.                 }
  176.                 break;
  177.             default:
  178.                 break;
  179.         }
  180.         door->type = type;
  181.         door->speed = speed;
  182.         door->topwait = VDOORWAIT;
  183.     }
  184.     return(retcode);
  185. }
  186.  
  187. //==================================================================
  188. //
  189. //    EV_VerticalDoor : open a door manually, no tag value
  190. //
  191. //==================================================================
  192. void EV_VerticalDoor(line_t *line, mobj_t *thing)
  193. {
  194.     player_t        *player;
  195.     int                secnum;
  196.     sector_t        *sec;
  197.     vldoor_t        *door;
  198.     int                side;
  199.     
  200.     side = 0; // only front sides can be used
  201. //
  202. //    Check for locks
  203. //
  204.     player = thing->player;
  205.     switch(line->special)
  206.     {
  207.         case 26: // Blue Lock
  208.         case 32:
  209.             if(!player)
  210.             {
  211.                 return;
  212.             }
  213.             if(!player->keys[key_blue])
  214.             {
  215.                 P_SetMessage(player, TXT_NEEDBLUEKEY, false);
  216.                 S_StartSound(NULL, sfx_plroof);
  217.                 return;
  218.             }
  219.             break;
  220.         case 27: // Yellow Lock
  221.         case 34:
  222.             if(!player)
  223.             {
  224.                 return;
  225.             }
  226.             if(!player->keys[key_yellow])
  227.             {
  228.                 P_SetMessage(player, TXT_NEEDYELLOWKEY, false);
  229.                 S_StartSound(NULL, sfx_plroof);
  230.                 return;
  231.             }
  232.             break;
  233.         case 28: // Green Lock
  234.         case 33:
  235.             if(!player)
  236.             {
  237.                 return;
  238.             }
  239.             if(!player->keys[key_green])
  240.             {
  241.                 P_SetMessage(player, TXT_NEEDGREENKEY, false);
  242.                 S_StartSound(NULL, sfx_plroof);
  243.                 return;
  244.             }
  245.             break;
  246.     }
  247.  
  248.     // if the sector has an active thinker, use it
  249.     sec = sides[line->sidenum[side^1]].sector;
  250.     secnum = sec-sectors;
  251.     if(sec->specialdata)
  252.     {
  253.         door = sec->specialdata;
  254.         switch(line->special)
  255.         {
  256.             case 1: // ONLY FOR "RAISE" DOORS, NOT "OPEN"s
  257.             case 26:
  258.             case 27:
  259.             case 28:
  260.                 if(door->direction == -1)
  261.                 {
  262.                     door->direction = 1; // go back up
  263.                 }
  264.                 else
  265.                 {
  266.                     if(!thing->player)
  267.                     { // Monsters don't close doors
  268.                         return;
  269.                     }
  270.                     door->direction = -1; // start going down immediately
  271.                 }
  272.                 return;
  273.         }
  274.     }
  275.  
  276.     // for proper sound
  277.     switch(line->special)
  278.     {
  279.         case 1: // NORMAL DOOR SOUND
  280.         case 31:
  281.             S_StartSound((mobj_t *)&sec->soundorg, sfx_doropn);
  282.             //S_StartSound((mobj_t *)&sec->soundorg, sfx_dormov);
  283.             break;
  284.         default: // LOCKED DOOR SOUND
  285.             S_StartSound((mobj_t *)&sec->soundorg, sfx_doropn);
  286.             //S_StartSound((mobj_t *)&sec->soundorg, sfx_dormov);
  287.             break;
  288.     }
  289.  
  290.     //
  291.     // new door thinker
  292.     //
  293.     door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0);
  294.     P_AddThinker(&door->thinker);
  295.     sec->specialdata = door;
  296.     door->thinker.function = T_VerticalDoor;
  297.     door->sector = sec;
  298.     door->direction = 1;
  299.     switch(line->special)
  300.     {
  301.         case 1:
  302.         case 26:
  303.         case 27:
  304.         case 28:
  305.             door->type = normal;
  306.             break;
  307.         case 31:
  308.         case 32:
  309.         case 33:
  310.         case 34:
  311.             door->type = open;
  312.             line->special = 0;
  313.             break;
  314.     }
  315.     door->speed = VDOORSPEED;
  316.     door->topwait = VDOORWAIT;
  317.     
  318.     //
  319.     // find the top and bottom of the movement range
  320.     //
  321.     door->topheight = P_FindLowestCeilingSurrounding(sec);
  322.     door->topheight -= 4*FRACUNIT;
  323. }
  324.  
  325. //==================================================================
  326. //
  327. //    Spawn a door that closes after 30 seconds
  328. //
  329. //==================================================================
  330. void P_SpawnDoorCloseIn30(sector_t *sec)
  331. {
  332.     vldoor_t *door;
  333.  
  334.     door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0);
  335.     P_AddThinker(&door->thinker);
  336.     sec->specialdata = door;
  337.     sec->special = 0;
  338.     door->thinker.function = T_VerticalDoor;
  339.     door->sector = sec;
  340.     door->direction = 0;
  341.     door->type = normal;
  342.     door->speed = VDOORSPEED;
  343.     door->topcountdown = 30*35;
  344. }
  345.  
  346. //==================================================================
  347. //
  348. //    Spawn a door that opens after 5 minutes
  349. //
  350. //==================================================================
  351. void P_SpawnDoorRaiseIn5Mins(sector_t *sec, int secnum)
  352. {
  353.     vldoor_t *door;
  354.  
  355.     door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0);
  356.     P_AddThinker(&door->thinker);
  357.     sec->specialdata = door;
  358.     sec->special = 0;
  359.     door->thinker.function = T_VerticalDoor;
  360.     door->sector = sec;
  361.     door->direction = 2;
  362.     door->type = raiseIn5Mins;
  363.     door->speed = VDOORSPEED;
  364.     door->topheight = P_FindLowestCeilingSurrounding(sec);
  365.     door->topheight -= 4*FRACUNIT;
  366.     door->topwait = VDOORWAIT;
  367.     door->topcountdown = 5*60*35;
  368. }
  369.